#include "CustomersModel.h"

#include <QBrush>
#include <QFile>
#include <assert.h>
#include <QDebug>
#include "CustomersParser.h"

using namespace ecocity;

const uint CustomersModel::s_columns = 6;

CustomersModel::CustomersModel( const std::vector< Customer >& customers,
                              QObject *parent )
    : QStandardItemModel( parent )
{
    for ( size_t row = 0; row < customers.size( ); ++row )
    {
        add_new_customer( customers[ row ] );
    }
}

//---------------------------------------------------------------

void
CustomersModel::reset( const std::vector< Customer >& customers )
{
    // Do not call clear cause columns resize again
    // clear( );
    removeRows( 0, rowCount() );

    for ( size_t row = 0; row < customers.size( ); ++row )
    {
        add_new_customer( customers[ row ] );
    }
}

//---------------------------------------------------------------

QVariant
CustomersModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
    if ( role != Qt::DisplayRole || orientation != Qt::Horizontal )
    {
        return QVariant();
    }

    switch( section )
    {
    case CUSTOMER_ID: return QString( "Id" );
    case CUSTOMER_NAME: return QString( "Nombre" );
    case CUSTOMER_ADDRESS: return QString( "Direccion" );
    case CUSTOMER_PHONE: return QString( "Telefono" );
    case CUSTOMER_NIF: return QString( "NIF" );
    case CUSTOMER_PRICE_TYPE: return QString( "Tipo de cargo" );

    default:
        return QVariant();
    }
}

//---------------------------------------------------------------

Qt::ItemFlags
CustomersModel::flags ( const QModelIndex & index ) const
{
    if ( index.column() == CUSTOMER_ID
         || index.column() == CUSTOMER_PRICE_TYPE )
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable; // No editable items
    else
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
}

//---------------------------------------------------------------

bool
CustomersModel::add_new_customer( const Customer& customer )
{
    qDebug() << "\nCustomerModel add new customer\n" << endl;

    QStandardItem* id = new QStandardItem;

    id->setData( customer.id( ), Qt::EditRole );

    QList<QStandardItem*> items;

    items << id
          << new QStandardItem( customer.name( ) )
          << new QStandardItem( customer.address( ) )
          << new QStandardItem( customer.phone( ) )
          << new QStandardItem( customer.nif( ) )
          << new QStandardItem( Customer::to_string( customer.type( ) ) );

    if ( (uint)items.size( ) != s_columns )
    {
        // Ensure you don't forget anything
        assert( 0 );
        return false;
    }

    insertRow( rowCount(), items );

    return true;
}

//---------------------------------------------------------------

Customer
CustomersModel::customer( const QModelIndex &index ) const
{
    int id = data( this->index( index.row( ), CUSTOMER_ID ) ).toInt( );
    QString name = data( this->index( index.row( ), CUSTOMER_NAME ) ).toString( );
    QString address = data( this->index( index.row( ), CUSTOMER_ADDRESS ) ).toString();
    QString phone = data( this->index( index.row( ), CUSTOMER_PHONE ) ).toString();
    QString nif = data( this->index( index.row( ), CUSTOMER_NIF ) ).toString();

    QString type = data( this->index( index.row( ), CUSTOMER_PRICE_TYPE ) ).toString();
    Customer::TYPE customer_type = Customer::to_customer_type( type );

    Customer customer( id,
                       name,
                       address,
                       phone,
                       nif,
                       customer_type );

    return customer;
}

//---------------------------------------------------------------

void
CustomersModel::save( const QString &file_name )
{
    if( file_name.isEmpty( ) )
    {
        return;
    }

    QFile file( file_name );

    if ( !file.open( QIODevice::WriteOnly ) )
    {
        return;
    }

    QTextStream out( &file );

    for ( int row = 0; row < rowCount(); ++row )
    {
        for ( uint column = 0; column < s_columns; ++column )
        {
            switch ( column ) {
            case CUSTOMER_ID:
                out << item( row, column )->data( Qt::EditRole ).toInt();
                break;
            case CUSTOMER_NAME:
            case CUSTOMER_ADDRESS:
            case CUSTOMER_PRICE_TYPE:
            case CUSTOMER_NIF:
                out << item( row, column )->text();
                break;
            default:
                break;
            }

            if ( column < s_columns - 1 )
            {
                out << ",";
            }
        }

        out << "\n";
    }

    file.close();
}

//---------------------------------------------------------------

bool
CustomersModel::load( const QString &file_name )
{
    removeRows( 0, rowCount() );

    if( file_name.isEmpty( ) )
    {
        return false;
    }

    QFile file( file_name );

    if ( !file.open( QIODevice::ReadOnly ) )
    {
        return false;
    }

    QTextStream stream( &file );

    while ( !stream.atEnd() )
    {
        QString line = stream.readLine( );

        while( line.startsWith( '#' ) )
        {
            line = stream.readLine( );
        }

        std::vector<int> separators =
                CustomerParser::separators_in_line( line );

        // list should contain 9 separators
        //      id,Name,Address,PriceType,Num Invoices,Total sold
        // i.e. 1,Pan rustic,Pan rustic eco,La Fogaina, 8%, 30%, 25%, 20%, 2EUR
        if( separators.size() != s_columns )
        {
            assert( 0 );
            return false;
        }

        const Customer customer = CustomerParser::to_customer( line, ';' );

        add_new_customer( customer );
    }

    file.close();

    return true;
}

//---------------------------------------------------------------

int
CustomersModel::get_biggest_id( )
{
    int max_id = -1;

    for ( int i = 0; i < rowCount( ); ++i )
    {
        int id = data( index( i, CUSTOMER_ID ) ).toInt( );

        if ( id > max_id )
        {
            max_id = id;
        }
    }

    return max_id;

}
